package com.learning.crpc.provider;

import com.alibaba.fastjson.JSONObject;
import com.learning.crpc.Application;
import com.learning.crpc.model.CrpcRequest;
import com.learning.crpc.model.CrpcResponse;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import org.springframework.context.ApplicationContext;

import java.lang.reflect.Method;

/**
 * @program: diy_rpc
 * @description:
 * @author: CaoYong
 * @create: 2021-07-01 13:50
 **/
public class NettyProviderHandler extends SimpleChannelInboundHandler<CrpcRequest> {

    ApplicationContext  applicationContext;

    public NettyProviderHandler(ApplicationContext applicationContext) {
        super();
        this.applicationContext = applicationContext;
    }

    @Override
    protected void channelRead0(ChannelHandlerContext channelHandlerContext, CrpcRequest crpcRequest) throws Exception {
//        ByteBuf request = (ByteBuf) msg;
//        byte[] msgs = new byte[request.readableBytes()];
//        request.readBytes(msgs);
//
//        String requestStr = new String(msgs);
//        CrpcRequest crpcRequest = JSONObject.parseObject(requestStr, CrpcRequest.class);
        String result = callService(crpcRequest);
        CrpcResponse response = new CrpcResponse();
        response.setCode(200);
        response.setContent(result);
        response.setRequestId(crpcRequest.getId());

        channelHandlerContext.writeAndFlush(response);

    }

    private String callService(CrpcRequest crpcRequest) throws Exception{
        String className = crpcRequest.getClassName();
        String methodName = crpcRequest.getMethodName();
        Class[] parameterTypes = crpcRequest.getParameterTypes();
        Object[] arguments = crpcRequest.getArguments();
        Class<?> serviceClass = Class.forName(className);
        Object serviceBean = applicationContext.getBean(serviceClass);
        Method method = serviceBean.getClass().getMethod(methodName, parameterTypes);
        Object invoke = method.invoke(serviceBean, arguments);
        return invoke.toString();
    }
}
